﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Net;
using System.IO;
using APILocawebGateway.HTMLHelper;
using System.Collections.Specialized;
using System.Runtime.CompilerServices;
using System.Net.Mail;
using System.Net;

[assembly: InternalsVisibleTo("TestProject")]
namespace APILocawebGateway
{
    /// <summary>
    /// Classe de apoio ao processamento da forma de pagamento VISA
    /// </summary>

    internal sealed class Utilidades
    {



        #region Format

        public static String FormatarPreco(Decimal price)
        {
            String priceAsString = price.ToString();
            if (priceAsString.Contains(","))
                priceAsString = priceAsString.Remove(priceAsString.IndexOf(","));

            return (priceAsString.Replace(",", "").Replace(".", "") + "00");
        }

        public static string FormatarDamount(Decimal price)
        {
            String priceAsString = price.ToString("C");

            return (priceAsString);
        }

        #endregion

        /// <summary>
        /// Este método gera uma query string usando um NameValueCollection como base
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public static string GerarQueryString(NameValueCollection query)
        {
            StringBuilder queryString = new StringBuilder();
            foreach (var item in query.AllKeys)
            {
                queryString.Append(item);
                queryString.Append("=");
                queryString.Append(query[item]);
                queryString.Append("&");
            }
            queryString.Remove(queryString.Length - 1, 1);// Removendo o ultimo &

            return queryString.ToString();
        }

        /// <summary>
        /// Este método Realiza uma requisição modo POST
        /// </summary>
        /// <param name="query">Dados que serão utilizados para formar a queryString, Dados devem estar no padrão NameValueCollection</param>
        /// <returns></returns>
        public static string RealizarRequisicaoModoPost(NameValueCollection query)
        {
            //Convertemos os dados
            byte[] buffer = Encoding.UTF8.GetBytes(GerarQueryString(query));

            //Inicialização, utilize a url do serviço
            HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(Configuracao.URLCOMPONENTELOCAWEB);

            //Utilizamos o método Post, por isso o buffer é necessário
            webReq.Method = WebRequestMethods.Http.Post;

            //form contentType para o envio das variáveis
            webReq.ContentType = "application/x-www-form-urlencoded";

            //O tamanho do buffer é utilizado como contentlength.
            webReq.ContentLength = buffer.Length;

            //Aumenta o TimeOut
            webReq.Timeout = 120000;

            //Abre um stream para gravação das variáveis
            Stream postData = webReq.GetRequestStream();

            //Grava remotamente e fecha o stream. O fechamento é sempre importante!
            postData.Write(buffer, 0, buffer.Length);
            postData.Close();

            //Faz o tratamento da resposta
            HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse();

            //Lê a resposta como string para saída.
            Stream resposta = webResp.GetResponseStream();
            StreamReader _resposta = new StreamReader(resposta);
            webReq = null;
            postData = null;
            webResp = null;

            return _resposta.ReadToEnd();
        }


        /// <summary>
        /// Este método realiza uma requisição post passando os dados contidos no objeto query
        /// </summary>
        /// <param name="url"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        public static string RealizarRequisicaoModoPost(String url, NameValueCollection query)
        {
            //Convertemos os dados
            byte[] buffer = Encoding.UTF8.GetBytes(GerarQueryString(query));

            //Inicialização, utilize a url do serviço
            HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(url);

            //Utilizamos o método Post, por isso o buffer é necessário
            webReq.Method = WebRequestMethods.Http.Post;

            //form contentType para o envio das variáveis
            webReq.ContentType = "application/x-www-form-urlencoded";

            //O tamanho do buffer é utilizado como contentlength.
            webReq.ContentLength = buffer.Length;

            //Aumenta o TimeOut
            webReq.Timeout = 120000;

            //Abre um stream para gravação das variáveis
            Stream postData = webReq.GetRequestStream();

            //Grava remotamente e fecha o stream. O fechamento é sempre importante!
            postData.Write(buffer, 0, buffer.Length);
            postData.Close();

            //Faz o tratamento da resposta
            HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse();

            //Lê a resposta como string para saída.
            Stream resposta = webResp.GetResponseStream();
            StreamReader _resposta = new StreamReader(resposta);

            return _resposta.ReadToEnd();
        }

        /// <summary>
        /// Este método realiza uma requisição modo GET
        /// </summary>
        /// <param name="query">Dados que serão utilizados para formar a queryString, Dados devem estar no padrão NameValueCollection</param>
        /// <returns></returns>
        public static String RealizarRequisicaoModoGet(NameValueCollection query)
        {

            //Inicialização, utilize a url do serviço
            HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(Configuracao.URLCOMPONENTELOCAWEB + "?" + GerarQueryString(query));
            //Utilizamos o método Post, por isso o buffer é necessário
            webReq.Method = WebRequestMethods.Http.Get;
            webReq.Timeout = 2 * 60 * 1000;

            var respostaRequisicao = webReq.GetResponse();
            StreamReader streamIn = new StreamReader(respostaRequisicao.GetResponseStream());
            String resposta = streamIn.ReadToEnd();
            respostaRequisicao.Close();
            streamIn.Close();
            return resposta;
        }

        /// <summary>
        /// Este método realiza uma requisição modo GET
        /// </summary>
        /// <param name="url">URL para a qual a requisição será realizada</param>
        /// <param name="query"> queryString da requisição</param>
        /// <returns></returns>
        public static String RealizarRequisicaoModoGet(String url, NameValueCollection query)
        {

            //Inicialização, utilize a url do serviço
            HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(url + "?" + GerarQueryString(query));
            //Utilizamos o método Post, por isso o buffer é necessário
            webReq.Method = WebRequestMethods.Http.Get;
            webReq.Timeout = 2 * 60 * 1000;

            var respostaRequisicao = webReq.GetResponse();
            StreamReader streamIn = new StreamReader(respostaRequisicao.GetResponseStream());
            String resposta = streamIn.ReadToEnd();
            respostaRequisicao.Close();
            streamIn.Close();
            return resposta;
        }


        /// <summary>
        /// Este método formata uma string no formato XML
        /// </summary>
        /// <param name="tagNameToRender"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static String RenderizarCampoRetorno(String tagNameToRender, String value)
        {
            StringBuilder strBuilder = new StringBuilder();
            strBuilder.Append("<" + tagNameToRender + ">");
            strBuilder.Append(value);
            strBuilder.Append("</" + tagNameToRender + ">");
            return strBuilder.ToString();


        }


        /// <summary>
        /// Este método extrai o valor de uma determinada tag XML em uma String
        /// </summary>
        /// <param name="resul"></param>
        /// <param name="tagRender">O nome da tag, sem os sinais de maior e menor
        /// Exemplo: caso a tag seja <free> deve ser passado apenas free</param>
        /// <returns></returns>
        public static String ObterValorCampoRetorno(String resul, String tagNameRender)
        {
            return ExtrairString(resul, "<" + tagNameRender + ">", "</" + tagNameRender + ">");
        }

        #region Métodos usados para Extrair String

        private static string ExtrairString(string fonte, string delimitadorInicial, string delimitadorFinal)
        {
            return ExtrairString(fonte, delimitadorInicial, delimitadorFinal, false, false);
        }

        private static string ExtrairString(string fonte, string delimitadorInicial, string delimitadorFinal, bool CaseSensitive, bool permititDelimitadorFinalAusente)
        {
            int At1, At2;

            if (string.IsNullOrEmpty(fonte))
                return "";

            if (CaseSensitive)
            {
                At1 = fonte.IndexOf(delimitadorInicial);
                if (At1 == -1)
                    return "";

                At2 = fonte.IndexOf(delimitadorFinal, At1 + delimitadorInicial.Length);
            }
            else
            {
                string Lower = fonte.ToLower();
                At1 = Lower.IndexOf(delimitadorInicial.ToLower());
                if (At1 == -1)
                    return "";

                At2 = Lower.IndexOf(delimitadorFinal.ToLower(), At1 + delimitadorInicial.Length);
            }

            if (permititDelimitadorFinalAusente && At2 == -1)
                return fonte.Substring(At1 + delimitadorInicial.Length);

            if (At1 > -1 && At2 > 1)
                return fonte.Substring(At1 + delimitadorInicial.Length, At2 - At1 - delimitadorInicial.Length);

            return "";
        }

        #endregion

    }
}
